/**
 * 
 */
package info.niwota.profile;

import info.niwota.profile.web.Helper;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * @author qiangli
 * 
 */
public class EditProfileActivity extends Activity implements OnClickListener, OnItemSelectedListener, OnCheckedChangeListener {

	private static final String TAG = "EditProfileActivity";

	private static final int DIALOG_BIRTHDAY = 1;

	private static final int RC_PICK_PHOTO = 1;

	private class LocationTask extends AsyncTask<Void, Void, Void> {
		private String location = null;
		
		@Override
		protected Void doInBackground(Void... params) {
			final Context ctx = EditProfileActivity.this;
			try {
				location = Locations.getLocation(ctx);
			} catch (Exception e) {
				e.printStackTrace();
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			try {
				if (location != null) {
					TextView myloc = (TextView) findViewById(R.id.profile_mylocation_view);
					myloc.setText(location);
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

	}

	private LocationTask locationTask;

	
	private final Handler handler = new Handler();
	
	private final BroadcastReceiver intentReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
				//
			}
			updateTime();
		}
	};

	private boolean dirty = false;
	
	private class MyTextWatcher implements TextWatcher {
		public void afterTextChanged(Editable edit) {
			dirty = true;
		}

		public void beforeTextChanged(CharSequence edit, int start, int count,
				int after) {
		}

		public void onTextChanged(CharSequence edit, int start, int before,
				int count) {
		}	
	}
	
	private DatePickerDialog.OnDateSetListener birthdaySetListener = new DatePickerDialog.OnDateSetListener() {

		public void onDateSet(DatePicker view, int year, int monthOfYear,
				int dayOfMonth) {
			updateDobDisplay(year, monthOfYear, dayOfMonth);
		}
	};


	private Calendar dob = Calendar.getInstance();
	
	private void updateDobDisplay(int year, int month, int day) {
		dirty = true;
		//
		SimpleDateFormat df = new SimpleDateFormat(
				getString(R.string.dob_format));
		
		dob.set(Calendar.MONTH, month);
		dob.set(Calendar.DAY_OF_MONTH, day);
		dob.set(Calendar.YEAR, year);
		
		//
		Date now = new Date();
		boolean valid = dob.getTime().before(now);
		String t = valid ? df.format(dob.getTime()) : "";
		
		showDob(t);
	}

	private void showDob(String t) {
		Button birthDay = (Button) findViewById(R.id.profile_birthday);
		birthDay.setText(t);
	}

	private TextView mytime;

	private IntentFilter timeFilter;

	private void updateTime() {
		String date = Dates.getDateTime(this);
		mytime.setText(date);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_LEFT_ICON);
		
		setContentView(R.layout.profile_edit);

		setTitle(R.string.action_edit_profile);
		getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
				R.drawable.icon);
		//
		ImageView pic = (ImageView) findViewById(R.id.profile_photo);
		pic.setOnClickListener(this);
		registerForContextMenu(pic);
		
		//date
		mytime = (TextView) findViewById(R.id.profile_mytime_view);
		
		timeFilter = new IntentFilter();
		timeFilter.addAction(Intent.ACTION_TIME_TICK);
		timeFilter.addAction(Intent.ACTION_TIME_CHANGED);
		timeFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
		
		//dob
		Button bday = (Button) findViewById(R.id.profile_birthday);
		bday.setOnClickListener(this);
		registerForContextMenu(bday);

		//
		startLoad();
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (Debug.DEBUG) {
			Log.d(TAG, "onResume");
		}
		registerReceiver(intentReceiver, timeFilter, null, handler);

	}

	private void startLoad() {
		updateTime();
		
		loadPreference();

		setPhoto();

		loadLocation();
	}

	private void loadLocation() {
		try {
			locationTask = new LocationTask();
			locationTask.execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (Debug.DEBUG) {
			Log.d(TAG, "onPause");
		}
		unregisterReceiver(intentReceiver);
		
		cancelLoad();
		
		savePreference();
		
	}

	private void cancelLoad() {
		try {
			if (locationTask != null) {
				locationTask.cancel(true);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			locationTask = null;
		}
	}

	private void loadPreference() {
		final SharedPreferences p = PreferenceManager
				.getDefaultSharedPreferences(this);

		EditText name = (EditText) findViewById(R.id.profile_name);
		name.setText(p.getString(Preferences.PROFILE_NAME, ""));
		
		CheckBox loc = (CheckBox) findViewById(R.id.profile_mylocation);
		loc.setChecked(p.getBoolean(Preferences.PROFILE_LOCATION, false));
		CheckBox time = (CheckBox) findViewById(R.id.profile_mytime);
		time.setChecked(p.getBoolean(Preferences.PROFILE_TIME, false));

		//
		Spinner gender = (Spinner) findViewById(R.id.profile_gender);
		String prefGender = p.getString(Preferences.PROFILE_GENDER, null);
		int pos = 0; // Gender
		if (prefGender != null) {
			try {
				pos = Integer.parseInt(prefGender);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		gender.setSelection(pos % 3);
		Button btnDob = (Button) findViewById(R.id.profile_birthday);
		String dobs = p.getString(Preferences.PROFILE_DOB, null);
		if (dobs != null) {
			try {
				SimpleDateFormat df = new SimpleDateFormat(
						getString(R.string.dob_format));
				dob.setTime(df.parse(dobs));
			} catch (ParseException e) {
					//e.printStackTrace();
					dobs = null;
			}
		}
		btnDob.setText(dobs);
		
		EditText msg = (EditText) findViewById(R.id.profile_welcome);
		msg.setText(p.getString(Preferences.PROFILE_WELCOME, ""));

		EditText call = (EditText) findViewById(R.id.profile_phone);
		call.setText(p.getString(Preferences.PROFILE_CALL, ""));
		EditText text = (EditText) findViewById(R.id.profile_texting);
		text.setText(p.getString(Preferences.PROFILE_TEXT, ""));
		EditText email = (EditText) findViewById(R.id.profile_email);
		email.setText(p.getString(Preferences.PROFILE_EMAIL, ""));
		EditText chat = (EditText) findViewById(R.id.profile_im);
		chat.setText(p.getString(Preferences.PROFILE_CHAT, ""));
		
		EditText web = (EditText) findViewById(R.id.profile_website);
		web.setText(p.getString(Preferences.PROFILE_WEBSITE, ""));
		EditText addr = (EditText) findViewById(R.id.profile_address);
		addr.setText(p.getString(Preferences.PROFILE_ADDRESS, ""));
		
		EditText note = (EditText) findViewById(R.id.profile_note);
		note.setText(p.getString(Preferences.PROFILE_NOTE, ""));
		
		//
		//register text watcher
		TextWatcher tw = new MyTextWatcher();
		
		loc.setOnCheckedChangeListener(this);
		time.setOnCheckedChangeListener(this);
		gender.setOnItemSelectedListener(this);
		
		name.addTextChangedListener(tw);
		msg.addTextChangedListener(tw);
		call.addTextChangedListener(tw);
		text.addTextChangedListener(tw);
		email.addTextChangedListener(tw);
		chat.addTextChangedListener(tw);
		addr.addTextChangedListener(tw);
		web.addTextChangedListener(tw);
		note.addTextChangedListener(tw);
		
		dirty = false;
	}

	private void savePreference() {
		if (Debug.DEBUG) {
			Log.d(TAG, "savePreference: " + dirty);
		}
		
		setResult(dirty ? RESULT_OK : RESULT_CANCELED);
		
		if (!dirty) {
			if (Debug.DEBUG) {
				Log.d(TAG, "No change, preference not saved.");
			}
			return;
		}

		final SharedPreferences pref = PreferenceManager
				.getDefaultSharedPreferences(this);
		SharedPreferences.Editor ed = pref.edit();

		EditText name = (EditText) findViewById(R.id.profile_name);
		ed.putString(Preferences.PROFILE_NAME, trim(name.getText().toString()));

		CheckBox loc = (CheckBox) findViewById(R.id.profile_mylocation);
		ed.putBoolean(Preferences.PROFILE_LOCATION, loc.isChecked());
		CheckBox time = (CheckBox) findViewById(R.id.profile_mytime);
		ed.putBoolean(Preferences.PROFILE_TIME, time.isChecked());
		
		//
		Spinner gender = (Spinner) findViewById(R.id.profile_gender);
		ed.putString(Preferences.PROFILE_GENDER, gender
				.getSelectedItemPosition()
				+ "");
		Button dob = (Button) findViewById(R.id.profile_birthday);
		ed.putString(Preferences.PROFILE_DOB, dob.getText().toString());
		
		EditText msg = (EditText) findViewById(R.id.profile_welcome);
		ed.putString(Preferences.PROFILE_WELCOME,
				trim(msg.getText().toString()));
		
		EditText call = (EditText) findViewById(R.id.profile_phone);
		ed.putString(Preferences.PROFILE_CALL,
				trim(call.getText().toString()));
		EditText text = (EditText) findViewById(R.id.profile_texting);
		ed.putString(Preferences.PROFILE_TEXT,
				trim(text.getText().toString()));
		EditText email = (EditText) findViewById(R.id.profile_email);
		ed.putString(Preferences.PROFILE_EMAIL, trim(email.getText()
				.toString()));
		EditText chat = (EditText) findViewById(R.id.profile_im);
		ed.putString(Preferences.PROFILE_CHAT,
				trim(chat.getText().toString()));

		EditText web = (EditText) findViewById(R.id.profile_website);
		ed.putString(Preferences.PROFILE_WEBSITE,
				trim(web.getText().toString()));
		EditText homeaddr = (EditText) findViewById(R.id.profile_address);
		ed.putString(Preferences.PROFILE_ADDRESS,
				trim(homeaddr.getText().toString()));

		EditText note = (EditText) findViewById(R.id.profile_note);
		ed.putString(Preferences.PROFILE_NOTE, trim(note.getText().toString()));
		
		//
		ed.putString(Preferences.PROFILE_MODIFIED, System.currentTimeMillis()+"");
		//
		ed.commit();
		
		if (Debug.DEBUG) {
			Log.d(TAG, "Changes saved");
		}
	}

	private void doPick() {
		try {
			Intent i = new Intent(this, PickPhotoActivity.class);
			startActivityForResult(i, RC_PICK_PHOTO);
		} catch (Exception e) {
			// e.printStackTrace();
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (Debug.DEBUG) {
			Log.d(TAG, "onActivityResult requestCode: " + requestCode
					+ " resultCode:" + resultCode + " == " + RESULT_OK
					+ " data: " + data);
		}
		
		if (requestCode == RC_PICK_PHOTO) {
			setPhoto();
		}
	}
	
	private static String trim(String s) {
		return (s == null ? "" : s.trim());
	}

	private void setPhoto() {
		Thread th = new Thread() {
			public void run() {
				try {
					updatePhoto();		
				} catch (Error e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		};

		th.start();
	}

	private void updatePhoto() {
		runOnUiThread(new Runnable() {
			public void run() {
				showPhoto();
			}
		});
	}
	
	private void showPhoto() {
		ImageView img = (ImageView) findViewById(R.id.profile_photo);
		try {
			File file = Helper.getMyPhotoThumbnail(this);

			if (file != null) {
				Bitmap bm = BitmapFactory.decodeFile(file.getPath());
				img.setImageBitmap(bm);
			} else {
				img.setImageResource(R.drawable.ic_menu_add_picture);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		int id = v.getId();
		if (Debug.DEBUG) {
			Log.d(TAG, " id: " + id + " view: " + v);
		}
		
		switch(id) {
		case R.id.profile_photo: {
			final String uri = Preferences.getProfilePhoto(this);
			if (!TextUtils.isEmpty(uri)) {
				MenuInflater inflater = getMenuInflater();
				inflater.inflate(R.menu.photo_context, menu);
			}
			break;
		}
		case R.id.profile_birthday: {
			Button btn = (Button) findViewById(R.id.profile_birthday);
			if (!TextUtils.isEmpty(btn.getText())) {
				MenuInflater inflater = getMenuInflater();
				inflater.inflate(R.menu.dob_context, menu);
			}
			break;
		}
		default:
		}
	}
	
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		int id = item.getItemId();
		switch(id) {
		case R.id.photo_view_context_menu_id:
			final String uri = Preferences.getProfilePhoto(this);
			if (!TextUtils.isEmpty(uri)) {
				Utils.startViewActivity(this, Uri.parse(uri), "image/*");
			}
			break;
		case R.id.photo_edit_context_menu_id:
			doPick();
			break;
		case R.id.photo_remove_context_menu_id:
			Preferences.setProfilePhoto(this, null);
			showPhoto(); 
			break;
		case R.id.dob_edit_context_menu_id:
			showDialog(DIALOG_BIRTHDAY);
			break;
		case R.id.dob_remove_context_menu_id:
			showDob(null);
			break;
		}
		return true;
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_BIRTHDAY:
			int year = dob.get(Calendar.YEAR);
			int month = dob.get(Calendar.MONTH);
			int day = dob.get(Calendar.DAY_OF_MONTH);
			DatePickerDialog d = new DatePickerDialog(this,
					birthdaySetListener, year, month, day);
			d.setTitle(getString(R.string.dob_dia_title));
			return d;
		default:
		}
		return null;
	}

	public void onClick(View v) {
		int id = v.getId();
		if (Debug.DEBUG) {
			Log.d(TAG, "view id: " + id);
		}
		switch (id) {
		case R.id.profile_birthday:
			showDialog(DIALOG_BIRTHDAY);
			break;
		case R.id.profile_photo:
			doPick();
			break;
		default:
		}
	}

	public void onItemSelected(AdapterView<?> av, View v, int arg2,
			long arg3) {
		int id = av.getId();
		if (id == R.id.profile_gender) { 
			dirty = true;
		}
	}

	public void onNothingSelected(AdapterView<?> arg0) {
	}

	public void onCheckedChanged(CompoundButton v, boolean checked) {
		int id = v.getId();
		if (id == R.id.profile_mylocation || id == R.id.profile_mytime) {
			dirty = true;
		}
	}
}
